#region  == Copyright == 
// =====================================================================
//  Microsoft Consulting Services France - Aymeric Mouillé - 2013
//  Projet     : Bulk Security Role Manager - Bulk Security Role Manager
//  Fichier    : SerializationHelper.cs (25/04/2013 17:19)
//  
//  Copyright (C) Microsoft Corporation.  All rights reserved.
// =====================================================================
#endregion

namespace CRM.BulkSecurityRoleManager
{
    #region  == Using == 
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Runtime.Serialization;
    using System.Text;
    using System.Xml;

    using Microsoft.Xrm.Sdk;

    #endregion

    public class SerializationHelper
    {
        #region Byte Array To Utf8 String
        /// <summary>
        /// Convert given byte array to UTF-8 string
        /// </summary>
        /// <param name="array">Byte array</param>
        /// <returns>
        /// UTF-8 string
        /// </returns>
        public static string ByteArrayToUtf8String(byte[] array)
        {
            UTF8Encoding encoding = new UTF8Encoding();
            return encoding.GetString(array);
        }
        #endregion

        #region Deserialize
        /// <summary>
        /// Convert given XML string to object
        /// </summary>
        /// <typeparam name="T">Object class</typeparam>
        /// <param name="filePath">The file path.</param>
        /// <returns>
        /// Casted object
        /// </returns>
        public static List<Entity> Deserialize(string filePath)
        {
            List<Entity> entityList = null;
            MemoryStream memoryStream = null;
            try
            {
                var document = new XmlDocument();
                document.Load(filePath);
                var xmlContent = Utf8StringToByteArray(document.OuterXml);

                memoryStream = new MemoryStream(xmlContent);
                using (var reader = XmlDictionaryReader.CreateTextReader(memoryStream, Encoding.UTF8, new XmlDictionaryReaderQuotas { MaxStringContentLength = int.MaxValue }, null))
                {
                    var serializer = new DataContractSerializer(typeof (List<Entity>), null, int.MaxValue, false, false, null, new KnownTypesResolver());
                    entityList = (List<Entity>)serializer.ReadObject(reader);
                }
            }
            finally
            {
                if (memoryStream != null)
                {
                    memoryStream.Dispose();
                }
            }
            return entityList;
        }
        #endregion

        #region Serialize
        /// <summary>
        /// Convert given object to XML string and save it to given path
        /// </summary>
        /// <param name="obj">Object to serialize</param>
        /// <param name="objType">Type of the obj.</param>
        /// <param name="filePath">The file path.</param>
        /// <returns>
        /// XML string
        /// </returns>
        public static void Serialize(object obj, Type objType, string filePath)
        {
            MemoryStream memoryStream = null;
            StreamReader streamReader = null;
            try
            {
                memoryStream = new MemoryStream();

                var serializer = new DataContractSerializer(objType, null, int.MaxValue, false, false, null, new KnownTypesResolver());

                var xmlWriter = new XmlTextWriter(memoryStream, Encoding.UTF8) { Formatting = Formatting.Indented };
                serializer.WriteObject(xmlWriter, obj);
                xmlWriter.Flush();

                memoryStream.Seek(0, SeekOrigin.Begin);
                streamReader = new StreamReader(memoryStream);
                using (var writer = new StreamWriter(filePath, false))
                {
                    writer.Write(streamReader.ReadToEnd());
                }
                streamReader.Close();
            }
            finally
            {
                if (streamReader != null)
                {
                    streamReader.Close();
                }
                if (memoryStream != null)
                {
                    memoryStream.Dispose();
                }
            }
        }
        #endregion

        #region Utf8 String To Byte Array
        /// <summary>
        /// Convert given UTF-8 string to byte array
        /// </summary>
        /// <param name="str">UTF-8 string</param>
        /// <returns>
        /// Byte array
        /// </returns>
        public static byte[] Utf8StringToByteArray(string str)
        {
            UTF8Encoding encoding = new UTF8Encoding();
            return encoding.GetBytes(str);
        }
        #endregion
    }
}
